/**
 * 
 */
package edu.ou.cs.youming.services;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.oxm.MediaType;

import edu.ou.cs.youming.jaxb.types.Example;
import edu.ou.cs.youming.jaxb.types.Label;
import edu.ou.cs.youming.jaxb.types.Tweet;

/**
 * @author Youming Lin
 * 
 */
public final class DataIO {
	public static final Iterable<Example> parseExamples(final String corpusPath,
			final String dir) throws IOException, JAXBException {
		// Step 1: Parse corpus.csv
		final HashMap<Long, Label> corpus = new HashMap<Long, Label>();
		final BufferedReader in = new BufferedReader(new FileReader(corpusPath));

		while (in.ready()) {
			final String line = in.readLine();
			final String tokens[] = line.replaceAll("\"", "").split(",");

			if (tokens[1].equalsIgnoreCase(Label.IRRELEVANT.toString())) {
				corpus.put(Long.parseLong(tokens[2]), Label.IRRELEVANT);
			}
			else if (tokens[1].equalsIgnoreCase(Label.NEGATIVE.toString())) {
				corpus.put(Long.parseLong(tokens[2]), Label.NEGATIVE);
			}
			else if (tokens[1].equalsIgnoreCase(Label.NEUTRAL.toString())) {
				corpus.put(Long.parseLong(tokens[2]), Label.NEUTRAL);
			}
			else if (tokens[1].equalsIgnoreCase(Label.POSITIVE.toString())) {
				corpus.put(Long.parseLong(tokens[2]), Label.POSITIVE);
			}
			else {
				System.out.println("[corpus]: " + tokens[2] + " has no label");
			}
		}

		in.close();

		// Step 2: Parse JSON files and match tweets with labels
		final ArrayList<Example> examples = new ArrayList<Example>();
		final JAXBContext jc = JAXBContext.newInstance(Tweet.class);
		final Unmarshaller unmarshaller = jc.createUnmarshaller();

		unmarshaller.setProperty("eclipselink.media-type", "application/json");
		unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);

		final File folder = new File(dir);

		for (final File f : folder.listFiles(new JSONFilter())) {
			final Tweet tweet = JAXBService.<Tweet> read(f, Tweet.class,
					MediaType.APPLICATION_JSON, false);

			if (tweet.id_str == null) {
				System.out.println("[" + f.getName() + "]: cannot parse file");
			}
			else {
				examples.add(new Example(corpus.get(tweet.id), tweet));
			}
		}

		return examples;
	}
}

final class JSONFilter implements FileFilter {
	@Override
	public boolean accept(final File pathname) {
		return pathname.getName().endsWith(".json");
	}
}